﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Hsp.Auto.Common.Utility
{
    /// <summary>
    /// 表转为泛型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class DataTableToList<T>
    {
        private readonly DataTable _dt;

        /// <summary>
        ///  构造函数
        /// </summary>
        /// <param name="dt">要转换的datatable</param>
        public DataTableToList(DataTable dt)
        {
            _dt = dt;
        }

        /// <summary>
        /// 将DataTable转成List实体类
        /// 设置实体类中属性为public和可写的属性
        /// </summary>
        /// <returns></returns>
        public List<T> ToList()
        {
            var list = new List<T>(); // 定义集合
            if (_dt == null || _dt.Rows.Count == 0)
            {
                return list;
            }
            Type objType = typeof(T); // 获得此模型的类型
            foreach (DataRow dr in _dt.Rows)
            {
                try
                {
                    object obj = System.Activator.CreateInstance(objType); //创建实例
                    foreach (System.Reflection.PropertyInfo prop in objType.GetProperties()) //遍历T类的所有属性
                    {
                        //if (prop.Name == "RowNumber")
                        //{
                        //    var a = prop.Name;
                        //}

                        try
                        {
                            //判断此属性是否有Setter，该属性不是公共类型，不可写，直接跳出，检查DataTable是否包含此列（列名==对象的属性名）
                            if (!prop.PropertyType.IsPublic || !prop.CanWrite || !_dt.Columns.Contains(prop.Name)) continue;

                            object value = dr[prop.Name]; // (dr[prop.Name] == DBNull.Value) ? null : 
                            //如果非空，则赋给对象的属性
                            if (value != DBNull.Value)
                            {
                                if (prop.PropertyType.Name == "Guid")
                                {
                                    value = (dr[prop.Name] == DBNull.Value) ? default : new Guid(dr[prop.Name].ToString());
                                }

                                //加一重if判断，如果属性值是int32类型的，就进行一次强制转换
                                if (prop.GetMethod.ReturnParameter.ParameterType.Name == "Int32")
                                {
                                    value = Convert.ToInt32(value);
                                }

                                prop.SetValue(obj, value, null);
                            }
                        }
                        catch (Exception)
                        {
                        }

                    }
                    list.Add((T)obj);
                }
                catch (Exception)
                {
                }
            }
            return list;
        }
    }

}
